package repositorys

import (
	"github.com/zhongshaofa/swan-jobs/internal/models"
	"github.com/zhongshaofa/swan-jobs/internal/plugin"
	"github.com/zhongshaofa/swan-jobs/internal/request"
	"gorm.io/gorm"
)

type ClientInterface interface {
	GetClientList(whereClient *models.Client) ([]*models.Client, error)
	Heartbeat(client *models.Client) error
	Create(client *models.Client) (*models.Client, error)
	Detail(clientId int) (*models.Client, error)
	Update(client *models.Client) error
	GetList(where *models.Client, pagination request.PaginationRequest) ([]*models.Client, int, error)
	Delete(ids []int) error
	SwitchStatus(ids []int, status int) error
}

type ClientRepository struct {
}

func (ClientRepository) GetClientList(whereClient *models.Client) ([]*models.Client, error) {
	var clientList []*models.Client

	db := plugin.DB
	db = db.Where(whereClient)
	result := db.Find(&clientList)

	if result.Error != nil {
		return nil, result.Error
	}

	return clientList, nil
}

func (ClientRepository) Heartbeat(client *models.Client) error {
	result := plugin.DB.Save(&client)
	return result.Error
}

func (ClientRepository) Create(client *models.Client) (*models.Client, error) {
	result := plugin.DB.Create(&client)
	if result.Error != nil {
		return nil, result.Error
	}
	return client, nil
}

func (ClientRepository) Detail(clientId int) (*models.Client, error) {
	client := models.Client{}
	result := plugin.DB.First(&client, clientId)
	if result.Error != nil {
		return nil, result.Error
	}
	return &client, nil
}

func (receiver ClientRepository) GetList(where *models.Client, pagination request.PaginationRequest) ([]*models.Client, int, error) {
	var list []*models.Client

	db := plugin.DB
	db = receiver.buildQuery(where, db).
		Limit(pagination.Limit).
		Offset((pagination.Page - 1) * pagination.Limit)
	result := db.Find(&list)

	var count int64
	receiver.buildQuery(where, db).Count(&count)

	if result.Error != nil {
		return nil, 0, result.Error
	}

	return list, int(count), nil
}

func (ClientRepository) Update(client *models.Client) error {
	result := plugin.DB.Save(&client)
	return result.Error
}

func (receiver ClientRepository) Delete(ids []int) error {
	result := plugin.DB.Delete(&models.Client{}, ids)
	if result.Error != nil {
		return result.Error
	}
	return nil
}

func (receiver ClientRepository) SwitchStatus(ids []int, status int) error {
	result := plugin.DB.Model(&models.Client{}).
		Where("id in (?)", ids).
		Update("status", status)
	if result.Error != nil {
		return result.Error
	}
	return nil
}

func (ClientRepository) buildQuery(where *models.Client, db *gorm.DB) *gorm.DB {
	if len(where.ClientName) > 0 {
		db = db.Where("client_name like ?", where.ClientName+"%")
	}
	if len(where.ClientCode) > 0 {
		db = db.Where("client_code like ?", where.ClientCode+"%")
	}
	if where.ID > 0 {
		db = db.Where("id = ?", where.ID)
	}
	if where.Status > 0 {
		db = db.Where("status = ?", where.Status)
	}
	if where.IsHeartbeat > 0 {
		db = db.Where("is_heartbeat = ?", where.IsHeartbeat)
	}
	return db
}
